#!/bin/sh /etc/rc.common
# Copyright (C) 2008-2020 OpenWrt.org
# Copyright (C) 2022 ImmortalWrt.org

START=99
USE_PROCD=0

DMAX=0
UMAX=0

start_n2n_qos() {

    local cfg="$1"

    local type
    config_get type "$cfg" TYPE

    case "$type" in
    edge)

        local qosdev qoslimit fwmark ifb_dev
        config_get qoslimit "$cfg" 'edge_limit_rate'

        [ "$qoslimit" = "0" ] && return 1

        config_get qosdev "$cfg" 'tunname'
        config_get fwmark "$cfg" 'fwmark'
        ifb_dev="ifb$fwmark"

        ip link add "$ifb_dev" type ifb
        ip link set dev "$ifb_dev" up
        tc qdisc del dev $qosdev handle ffff: ingress
        tc qdisc add dev $qosdev handle ffff: ingress
        tc filter add dev $qosdev parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev "$ifb_dev"

        #tc qdisc del dev ifb0 root
        #tc qdisc add dev ifb0 root handle 1: htb default 10
        #tc class add dev ifb0 parent 1:0 classid 1:1 htb rate 1Mbit burst 2k
        #tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 1Mbit  ceil 2Mbit

        # create root
        tc qdisc del dev "$ifb_dev" root
        tc qdisc add dev "$ifb_dev" root handle 1: hfsc  default 10
        tc class add dev "$ifb_dev" parent 1: classid 1:1 hfsc sc rate ${qoslimit}kbit ul rate ${qoslimit}kbit
        tc class add dev "$ifb_dev" parent 1:1 classid 1:10 hfsc sc umax ${UMAX}b dmax ${DMAX}ms rate ${qoslimit}kbit ul rate ${qoslimit}kbit
        tc class add dev "$ifb_dev" parent 1:1 classid 1:20 hfsc sc umax ${UMAX}b dmax ${DMAX}ms rate ${qoslimit}kbit ul rate ${qoslimit}kbit
        #tc class add dev ifb0 parent 1:10 classid 1:11 hfsc sc umax 2500b dmax 10ms rate 500kbit ul rate ${qoslimit}kbit
        #tc class add dev ifb0 parent 1:10 classid 1:12 hfsc sc umax 2500b dmax 10ms rate 500kbit ul rate 2000kbit

        # VPN interface upload speed control
        tc qdisc del dev $qosdev root
        tc qdisc add dev $qosdev root handle 1: hfsc default 10
        tc class add dev $qosdev parent 1: classid 1:1 hfsc sc umax ${UMAX}b dmax ${DMAX}ms rate ${qoslimit}kbit ul rate ${qoslimit}kbit
        tc class add dev $qosdev parent 1:1 classid 1:10 hfsc sc umax ${UMAX}b dmax ${DMAX}ms rate ${qoslimit}kbit ul rate ${qoslimit}kbit
        tc class add dev $qosdev parent 1:1 classid 1:20 hfsc sc umax ${UMAX}b dmax ${DMAX}ms rate ${qoslimit}kbit ul rate ${qoslimit}kbit

        # tc qd show dev edge0  # show qdisc
        # tc cl show dev edge0  # show class
        # tc fi show dev edge0  # show filter
    ;;
    esac
}

stop_n2n_qos(){

    local cfg="$1"

    local type
    config_get type "$cfg" TYPE

    case "$type" in
    edge)
        local tunname fwmark ifb_dev

        config_get tunname "$cfg" 'tunname'
        config_get fwmark "$cfg" 'fwmark'

        ifb_dev="ifb$fwmark"

        ip link set dev "$ifb_dev" down
        ip link delete "$ifb_dev"
        tc qdisc del dev "$ifb_dev" root
        tc qdisc del dev $tunname root
    ;;
    esac

}

start_service() {
    config_load 'n2n'
    config_foreach start_n2n_qos 'edge'
}

stop_service() {
    config_load 'n2n'
    config_foreach stop_n2n_qos 'edge'
}

reload_service() {
    stop
    start
}

service_triggers() {
    procd_add_reload_trigger "sdwan_for_qos"
}
